package com.nega.commons.spider.core;

import com.nega.commons.spider.IPSourcePool;
import com.nega.commons.spider.SpiderCoreService;
import com.nega.modules.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: Garcia
 * @CreateDate: 2019/5/10 0:01
 * @Description: IP池，获取IP和自动补充IP数量。一次性IP，获取完即删除
 */
@Slf4j
public class IPSourceOneTime implements IPSourcePool {

    private ReentrantLock mLock = new ReentrantLock();

    private List<String> pool = new ArrayList<>();

    @Resource
    private SpiderCoreService spiderCoreService;

    @Resource
    private ConfigService configService;

    private String IP_URL;

    private String CHECK_IP_URL;

    @Scheduled(fixedRate = 1000)
    @Async
    public void initIp(){
        if (pool.size()<40){
            log.info("一次性IP池当前数量:{}，IP池数量较低，开始补充>>>>>>",pool.size());
            try {
                if (StringUtils.isBlank(IP_URL)){
                    String ipUrl = configService.getProperty("ipUrl");
                    IP_URL=ipUrl;
                }
                Document document = Jsoup.connect(IP_URL).get();
                String ips = document.text();
                if (StringUtils.isNotBlank(ips)){
                    if (ips.contains("{")){
                        pool.add("FAIL");
                        return;
                    }
                    String [] ip = ips.split("\n");
                    String [] ip1 = ips.split(" ");
                    String [] ip2 = ips.split("\r");
                    String [] ip3 = ips.split("\n\r");
                    String [] ip4 = {};
                    if (ip.length>1){
                        ip4 = ip;
                    }else if (ip1.length>1){
                        ip4 = ip1;
                    }else if (ip2.length>1){
                        ip4 = ip2;
                    }else if (ip3.length>1){
                        ip4 = ip3;
                    }
                    for (String p:ip4) {
                        pool.add(p);
                    }
                }else {
                    pool.add("FAIL");
                }
                log.info("一次性IP池补充完成，当前数量:{}",pool.size());
            } catch (IOException e) {
                log.info("一次性IP池补充异常",e);
                pool.add("FAIL");
            }
        }
    }

    private String getVal(){
        mLock.lock();
        String val = pool.get(0);
        pool.remove(val);
        mLock.unlock();
        return val;
    }

    @Override
    public String getIp(){
        String ip;
        while (true){
            if (pool.size()>0){
                ip = getVal();
                if ("FAIL".equals(ip)){
                    break;
                }
                if (StringUtils.isBlank(CHECK_IP_URL)){
                    String checkIpUrl = configService.getProperty("checkIpUrl");
                    CHECK_IP_URL=checkIpUrl;
                }
                Document document = spiderCoreService.getDocument(CHECK_IP_URL,null,ip);
                if (document==null){
                    continue;
                }
                if ("<head>".contains(document.head().tagName())){
                    break;
                }
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                log.error("一次性IP池，线程睡眠异常");
            }
        }
        return ip;
    }

}
